package com.mf.service.utils.numericalProcedure;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.mf.bo.CodeDateScopedBo;
import com.mf.bo.calculateHistory.*;
import com.mf.entity.CodeHistory;
import com.mf.entity.WeekCodeHistory;
import com.mf.service.IWeekCodeHistoryService;
import com.mf.utils.StockGatherUtils;
import com.mf.vo.KDJVo;
import com.mf.vo.StockGatherVo;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.Resource;
import java.util.*;

/**
 * @Author: lmf
 * @Create: 2024/6/4 21:03
 * Description:  计算方案1  根据 stockGatherVo 计算出符合要求的股票
 */

@Slf4j
public class NumericalProcedure1 {
    public static String Calculate(StockGatherVo stockGatherVo) {
        final List<KDJVo> kdj = stockGatherVo.getKdj();
        if (kdj == null) {
            return null;
        }
        int size = kdj.size() - 1;
        return isBuyableDay(stockGatherVo, size);
    }


    /**
     * 判断当天是否盈利
     *
     * @param stockGatherVo      指标集合
     * @param i                  当前检查日期下标
     * @param calculateHistoryBo 单个代码在日期范围内成功失败的集合
     * @return 当前检查日期的盈利情况
     */
    public static ProfitBo getProfitBo(StockGatherVo stockGatherVo, int i, CalculateHistoryBo calculateHistoryBo) {
        final ProfitBo historyBo = new ProfitBo();
        historyBo.setDate(stockGatherVo.getDate()[i]);
        historyBo.setPrice(stockGatherVo.getK()[i][0]);
        // 如果买入价格小于后3天的价格
//        boolean a1 = stockGatherVo.getK()[i + 1][1] < stockGatherVo.getK()[i + 2][1];
//        boolean a2 = stockGatherVo.getK()[i + 1][1] < stockGatherVo.getK()[i + 3][1];
//        boolean a3 = stockGatherVo.getK()[i + 1][1] < stockGatherVo.getK()[i + 4][1];
//        boolean a4 = stockGatherVo.getK()[i + 1][1] < stockGatherVo.getK()[i + 5][1];
//        boolean a5 = stockGatherVo.getK()[i + 1][1] < stockGatherVo.getK()[i + 6][1];

        boolean a6 = false;
        for (int j = 0; j < 7; j++) {
            if (stockGatherVo.getK()[i + 1][0] * 1.02 < stockGatherVo.getK()[i + j + 1][1]) {
                a6 = true;
                break;
            }
        }
        // 止盈成功
        if (a6) {
            historyBo.setIsProfit(1);
            calculateHistoryBo.setProfitCount(calculateHistoryBo.getProfitCount() + 1);
        } else {
            //失败
            historyBo.setIsProfit(0);
            calculateHistoryBo.setFailCount(calculateHistoryBo.getFailCount() + 1);
            // 止损 5%
            final double v = stockGatherVo.getK()[i + 1][1] * 0.95;

            boolean error = false;
            for (int j = 10; j > 1; j--) {
                if (stockGatherVo.getK()[i + j][1] < v) {
                    error = true;
//                    System.out.println(stockGatherVo.getK()[i + j][1]+"对比价格");
//                    System.out.println("+======================================================");
//                    System.out.println(v + "止损价格");
//                    System.out.println("基准价格" + stockGatherVo.getK()[i + 1][1]);
//                    System.out.println("当时止损日期"+ stockGatherVo.getDate()[i + j]);
//                    System.out.println("当时的止损价格"+ stockGatherVo.getK()[i + j][1]);
                    break;
                }
            }
            if (error) {
                calculateHistoryBo.setStopLossCount(calculateHistoryBo.getStopLossCount() + 1);
            }
        }
        calculateHistoryBo.setTotalCount(calculateHistoryBo.getTotalCount() + 1);
        return historyBo;
    }

    /**
     * 盈利策略计算
     *
     * @param stockGatherVo 指标集合
     * @param size          当前检查日期下标
     * @return 是否盈利 盈利返回股票代码 否则返回null
     */

    public static String isBuyableDay(StockGatherVo stockGatherVo, int size) {
        final List<KDJVo> kdj = stockGatherVo.getKdj();

        final List<Double> cci = stockGatherVo.getCci();

//        final List<KDJVo> wKdj = weekStockGatherVo.getKdj();


        if (null == kdj || null == cci) {
            return null;
        }

//        boolean w1 =  wKdj.get(size).getJ() - wKdj.get(size).getK() >= 0;

        StringBuilder str = new StringBuilder();

        // k线
        double[][] k = stockGatherVo.getK();

        // 判断周线是否达到可买入的时机
//        boolean w1 =

        // j线大于k线(已经死叉)
        boolean a1 =
                kdj.get(size).getJ() - kdj.get(size).getK() >= 0;//&& kdj.get(size).getK() <



        // cci大于前一天的 并且 前一天的cci大于前前天的cci
        assert cci != null;
        boolean a2 = cci.get(size) > cci.get(size - 1); //&& cci.get(size - 1) > cci.get(size - 2);

        // kdj中的j线 必须大于前一天的
        boolean a3 = kdj.get(size).getJ() > kdj.get(size - 1).getJ();

        // 当天的收盘加和前9天对比必须有一天小于收盘价5%
        boolean a4 = false;
        for (int i = size; i > size - 10; i--) {
            if (k[size][1] * 1.10 < k[i][1]) {
                str.append("当天日期：").append(stockGatherVo.getDate()[i]).append(";");
                str.append("代码：").append(stockGatherVo.getDm()).append(";");
                str.append("当天价格:").append(k[size][1]).append("基准价格:").append(k[size][1] * 1.10).append("对比价:").append(k[i][1]).append(";");
                str.append("第几天进行对比").append(i).append(k[size - i][1]).append(";");
                a4 = true;
                break;
            }
        }

        // 如果
        if (a1 && a2  && a3 && a4) {
            str.append("j线大于k线的值:").append((kdj.get(size).getJ() > kdj.get(size - 1).getJ())).append(";");
            return stockGatherVo.getDm();
        }
        return null;
    }
}
